package service

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"

	"ddl_checker/internal/model"
)

// ExternalChecker 外部API检查器
type ExternalChecker struct {
	client *http.Client
}

// NewExternalChecker 创建外部检查器
func NewExternalChecker() *ExternalChecker {
	return &ExternalChecker{
		client: &http.Client{
			Timeout: 30 * time.Second,
		},
	}
}

// Check 执行外部API检查
func (ec *ExternalChecker) Check(ctx context.Context, apiURL string, req *model.ValidationRequest) (*model.ExternalCheckResult, error) {
	result := &model.ExternalCheckResult{
		IsValid:     false,
		Message:     "外部检查未执行",
		Details:     make(map[string]interface{}),
		APIResponse: make(map[string]interface{}),
	}

	// 创建请求体
	requestBody := map[string]interface{}{
		"ddl":             req.DDL,
		"rollback":        req.Rollback,
		"allowed_schemas": req.AllowedSchemas,
		"allowed_tables":  req.AllowedTables,
		"timestamp":       time.Now().Unix(),
	}

	jsonBody, err := json.Marshal(requestBody)
	if err != nil {
		result.Error = fmt.Sprintf("序列化请求失败: %v", err)
		return result, nil
	}

	// 创建HTTP请求
	httpReq, err := http.NewRequestWithContext(ctx, "POST", apiURL, bytes.NewBuffer(jsonBody))
	if err != nil {
		result.Error = fmt.Sprintf("创建请求失败: %v", err)
		return result, nil
	}

	httpReq.Header.Set("Content-Type", "application/json")
	httpReq.Header.Set("User-Agent", "DDL-Checker/1.0")

	// 发送请求
	resp, err := ec.client.Do(httpReq)
	if err != nil {
		result.Error = fmt.Sprintf("请求失败: %v", err)
		return result, nil
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		result.Error = fmt.Sprintf("读取响应失败: %v", err)
		return result, nil
	}

	// 解析响应
	var apiResponse map[string]interface{}
	if err := json.Unmarshal(body, &apiResponse); err != nil {
		result.Error = fmt.Sprintf("解析响应失败: %v", err)
		return result, nil
	}

	result.APIResponse = apiResponse

	// 解析检查结果
	if isValid, ok := apiResponse["valid"].(bool); ok {
		result.IsValid = isValid
	}

	if message, ok := apiResponse["message"].(string); ok {
		result.Message = message
	}

	if details, ok := apiResponse["details"].(map[string]interface{}); ok {
		result.Details = details
	}

	return result, nil
}
